import matplotlib.pyplot as plt
import numpy as np
import sympy as sp

# 导数与微分
x = sp.Symbol('x') # 符号x，自变量
y = 2 * x ** 3 + 3 * x ** 2 - 12 * x + 7 #公式
d = sp.diff(y,x,1) #求导函数(原函数，变量，阶数)
print('%s 的导函数为：%s' % (y, d))

'''
方式1：(1/a).evalf(subs=变量值, n=浮点位数)，n可以不写(1/a).(subs=变量值)
方式2：(1/a).subs({a:3}).evalf(n=6)
'''
subs={x: 3}
y_d = d.evalf(subs=subs, n=10) #代入导函数求解,(subs=变量值, n=浮点位数)
y_h = y.evalf(subs=subs, n=10) #代入原函数求解
print('将x= %s代入导函数求解为：%d' % (subs[x] ,y_d))
print('将x= %s代入原函数求解为：%d' % (subs[x] ,y_h))

'''
切线方程的一般形式是y=kx+b
，k是斜率（在上面已经求得）
，b是截距。我们只需要把切点坐标代入切线方程的一般形式
，便可以把b求出。最后，把k和b的数值代入y=kx+b，就可以得到切线方程。
y = k * x + b

@ 切线方程 ：Y = 导函数*(X - x0) + 原函数
'''
y_d = y_d * (x - subs[x]) + y_h


print('得出切线方程为：%s' % y_d)

# 绘制函数图和切线图
x = np.linspace(-5, 5, 1000)
y1 = 2 * x ** 3 + 3 * x ** 2 - 12 * x + 7 #原函数
#print(y1)
#y2 = 60.0*x + 112.0
y_values=[]
for i in x:
    y = y_d.evalf(subs={'x':i}) # x 的值依次带入y_d切线方程中
    y_values.append(y)

y2 = y_values
y2 = y2
#print(y2)

plt.title('函数y=2*x**3+3*x**2-12*x+7以及当x=-1时的切线')
plt.rcParams['font.sans-serif'] = ['SimHei'] #解决在绘图中中文显示乱码的问题。
plt.rcParams['axes.unicode_minus'] = False   #解决在绘图中中文显示乱码的问题。

plt.plot(x, y1)
plt.plot(x, y2)
plt.show()
